/**
 * 
 */
package com.miolr.module.core.config;

import java.beans.PropertyVetoException;
import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * @author iday
 * 
 */
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@ComponentScan({ "com.miolr.module.core.service", "com.miolr.module.core.dao" })
public class HibernateConfig {

	@Bean
	public SessionFactory sessionFactory() {
		LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
		factoryBean.setPackagesToScan("com.miolr.module.core.model");
		factoryBean.setDataSource(dataSource());
		factoryBean.setNamingStrategy(new MiolrNamingStrategy());
		Properties hibernateProperties = new Properties();
		hibernateProperties.setProperty("hibernate.dialect",
				"org.hibernate.dialect.MySQLDialect");
		hibernateProperties.setProperty("hibernate.query.substitutions",
				"true=1 false=0");
		hibernateProperties.setProperty("hibernate.show_sql", "true");
		hibernateProperties.setProperty("hibernate.use_outer_join", "false");
		hibernateProperties.setProperty(
				"hibernate.bytecode.use_reflection_optimizer", "true");
		hibernateProperties.setProperty("hibernate.connection.release_mode",
				"auto");
		hibernateProperties.setProperty(
				"hibernate.cache.use_second_level_cache", "true");
		hibernateProperties.setProperty("hibernate.cache.use_query_cache",
				"true");
		hibernateProperties.setProperty("hibernate.cache.region.factory_class",
				"org.hibernate.cache.ehcache.EhCacheRegionFactory");
		hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");
		hibernateProperties.setProperty("hibernate.jdbc.fetch_size", "50");
		hibernateProperties.setProperty("hibernate.jdbc.batch_size", "50");

		factoryBean.setHibernateProperties(hibernateProperties);
		try {
			factoryBean.afterPropertiesSet();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return factoryBean.getObject();
	}

	@Bean(destroyMethod = "close")
	public DataSource dataSource() {
		ComboPooledDataSource datasource = new ComboPooledDataSource();
		try {
			datasource.setDriverClass("com.mysql.jdbc.Driver");
			datasource.setJdbcUrl("jdbc:mysql://localhost/miolr?useUnicode=true&characterEncoding=UTF-8");
			datasource.setUser("miolr");
			datasource.setPassword("miolr");
			datasource.setMaxPoolSize(10);
			datasource.setMinPoolSize(2);
			datasource.setMaxIdleTime(1000);
		} catch (PropertyVetoException e) {
			throw new RuntimeException(e);
		}
		return datasource;
	}

	@Bean
	public PlatformTransactionManager txManager() {
		HibernateTransactionManager txManager = new HibernateTransactionManager();
		txManager.setSessionFactory(sessionFactory());
		txManager.setDataSource(dataSource());
		return txManager;
	}

}
